﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace CoreRay.IO
{
    public class ResourceManager
    {
        private Dictionary<string, ResourceHandler> resourceHandlers;
        private List<ResourceReader> resourceReaders;

        internal ResourceManager()
        {
            // Add common resource handlers
            this.resourceHandlers = new Dictionary<string, ResourceHandler>();
            this.AddResourceHandler(new ColladaResourceHandler());

            // Add common resource readers
            this.resourceReaders = new List<ResourceReader>();
            this.AddResourceReader(new FileSystemResourceReader(null));
            this.AddResourceReader(new FileSystemResourceReader("."));
        }

        public void AddResourceHandler(ResourceHandler resourceHandler)
        {
            foreach (var extension in resourceHandler.Extensions)
            {
                if (!this.resourceHandlers.ContainsKey(extension))
                {
                    this.resourceHandlers.Add(extension, resourceHandler);
                }
            }
        }

        public void AddResourceReader(ResourceReader resourceReader)
        {
            this.resourceReaders.Add(resourceReader);
        }

        public T ReadResource<T>(string path)
        {
            foreach (var resourceReader in this.resourceReaders)
            {
                if (resourceReader.ResourceExists(path))
                {
                    return this.ReadResource<T>(resourceReader.OpenResource(path), Path.GetExtension(path));
                }
            }

            return default(T);
        }

        public T ReadResource<T>(Stream input, string extension)
        {
            extension = extension.ToLower().Replace(".", string.Empty);

            if (!this.resourceHandlers.ContainsKey(extension) || this.resourceHandlers[extension].CanRead == false)
            {
                throw new ArgumentException(string.Format("The resource manager doesn't support the extension '{0}'.", extension), "extension");
            }

            return (T) this.resourceHandlers[extension].Read(input);
        }

        public void WriteResource(object input, Stream output, string extension)
        {
            extension = extension.ToLower().Replace(".", string.Empty);

            if (!this.resourceHandlers.ContainsKey(extension) || this.resourceHandlers[extension].CanWrite == false)
            {
                throw new ArgumentException(string.Format("The resource manager doesn't support the extension '{0}'.", extension), "extension");
            }

            this.resourceHandlers[extension].Write(input, output);
        }
    }
}
